var sfLocationService = {
    _map: null,
    _directionsDisplay: null,
    _directionsService: null,
    _dirResults: [],
    _queueLength: 0,
    mapOptions: {
	zoom: 10
    },
    getMap: function() {
	if (this.mapOptions.center == null) {
	    this.mapOptions.center = this.locationCollection.getCenter();
    	}
	if (this._map == null) {
	    this.mapOptions.mapTypeId = google.maps.MapTypeId.ROADMAP;
	    this._map = new google.maps.Map(document.getElementById('map_canvas'),
	    				    this.mapOptions);
	}
	return this._map;
    },
    getDirectionsService: function() {
	if (this._directionsService == null) {
	    this._directionsService = new google.maps.DirectionsService();
	}
	return this._directionsService;
    },
    getDirectionsDisplay: function() {
	if (this._directionsDisplay == null) {
	    this._directionsDisplay = new google.maps.DirectionsRenderer();
	    this._directionsDisplay.setMap(this.getMap());
	    this._directionsDisplay.setPanel(document.getElementById('directionsPanel'));
	}
	return this._directionsDisplay;
    },
    getDirectionsToLocation: function(start, destination, title) {
	var request = {
	    origin: start,
	    destination: destination,
	    travelMode: google.maps.TravelMode.DRIVING
	}
	var dirDisplay = this.getDirectionsDisplay();
	this.getDirectionsService().route(request, function(result, status) {
	    if (status == google.maps.DirectionsStatus.OK) {
		var resultDiv = $('<div class="dirResult"></div>');
		theLeg = result.routes[0].legs[0];
		console.log(result);
		
		var endAddress = theLeg.end_address;
		endAddress = endAddress.replace('148 Parking', '150 Parking');
		resultDiv.append('<h3 class="start">From: '+theLeg.start_address+'</h3>');
		resultDiv.append($('<span class="copyright">').text(result.routes[0].copyrights)); 
		$.each(result.routes[0].warnings, function(index, value) {
		    resultDiv.append($('<span class="warning">').text(value));
		});
		distanceSpan = $('<span class="distance">' + theLeg.distance.text + '</span>');
		timeSpan = $('<span class="duration">' + theLeg.duration.text + '</span>');
		resultDiv.append($('<h5 class="length"></h5>').append(distanceSpan).append(timeSpan));
		stepList = $('<ol></ol>', {"class": "steps"});
		steps = result.routes[0].legs[0].steps;
		for (step in steps) {
		    var stepLi = $('<li></li>');
		    stepLi.append('<span class="instruction">' + steps[step].instructions + '</span>');
		    var length = $('<span/>', {"class": "length"})
			.append('<span class="distance">' + steps[step].distance.text + '</span>')
			.append('<span class="duration">' + steps[step].duration.text + '</span>');
		    stepLi.append(length);
		    stepList.append(stepLi);
		}
		resultDiv.append(stepList);
		var result = new Object();
		result.title = title;
		result.div = resultDiv;
		result.duration = theLeg.duration.value;
		sfLocationService._dirResults.push(result);
		sfLocationService._queueLength--;
		if (sfLocationService._queueLength == 0) {
		    sfLocationService.processDirResults();
		}
	    }
	    else {
		if (status == google.maps.DirectionsStatus.NOT_FOUND) {
		    alert('Invalid location specified');
		}
		else if (status == google.maps.DirectionsStatus.ZERO_RESULTS) {
		    alert('No route could be found');
		}
		//					MAX_WAYPOINTS_EXCEEDED indicates that too many DirectionsWaypoints were provided in the DirectionsRequest. The maximum allowed waypoints is 8, plus the origin, and destination. Maps API Premier customers are allowed 23 waypoints, plus the origin, and destination.
		//					INVALID_REQUEST indicates that the provided DirectionsRequest was invalid.
		//					OVER_QUERY_LIMIT indicates the webpage has sent too many requests within the allowed time period.
		//					REQUEST_DENIED indicates the webpage is not allowed to use the directions service.
		//					UNKNOWN_ERROR 
		
	    }
	});
    },
    getDirectionsByDuration: function(start) {
	this._dirResults = [];
	results = [];
	this._queueLength = this.locationCollection.locations.length;
	for (ix in this.locationCollection.locations) {
	    currentLoc = this.locationCollection.locations[ix];
	    this.getDirectionsToLocation(start, currentLoc.getLatLng(), currentLoc.data.title);
	}
    },
    
    processDirResults: function() {
	//			$("#directionsPanel").empty();
	//			this._dirResults.sort(function(a,b) {
	//				return (a.duration < b.duration)	? -1
	//						: (a.duration > b.duration)	? 1
	//						: 0; 
	//			});
	for (ix in this._dirResults) {
	    var content_title = this._dirResults[ix].title;
	    $("#dir"+this._dirResults[ix].title).empty()
		.append(this._dirResults[ix].div);
	}
    },
    
    locationCollection: null,
    showLocations: function() {
	this.locationCollection.showMarkers(this.getMap());
    }

};

function sfLocation(data) {
    this.data = data;
    this.getLatLng = function() {
	return new google.maps.LatLng(this.data.lat, this.data.lng);
    };
    this.getMarker = function() {
	return new google.maps.Marker({
	    position: this.getLatLng(),
	    title: this.data.title
	})
    };
    return this;
}

var sfLocationCollection = {

    locations: new Array(),
    
    getCenter: function() {
	count=0;
	latSum=0;
	lngSum=0;
	for(index in this.locations) {
	    latSum += this.locations[index].data.lat
	    lngSum += this.locations[index].data.lng
	    count++
	}
	return new google.maps.LatLng(latSum/count, lngSum/count);
    },
    showMarkers: function(map) {
	for(index in this.locations) {
	    this.locations[index].getMarker().setMap(map);
	}
    }
};



$(function() {
    initMap();
    $('#getDirections').click(getDirections);
    $('form').bind('keypress', function(e) {
    	if (e.which == 13) { $('#getDirections').trigger('click'); return false; }
    });

});

function getDirections() {
    var startAddress = $('#startAddress').val();
    sfLocationService.getDirectionsByDuration(startAddress);
}

function detectBrowser() {
    var useragent = navigator.userAgent;

    if (useragent.indexOf('iPhone') != 1
	||  useragent.indexOf('Android') != 1) {
	mapdiv.style.width = '100%';
	mapdiv.style.height = '100%';
    }
    else {
	mapdiv.style.width = '600px';
	mapdiv.style.height = '800px';
    }
}


function loadLocations(prefix) {
    var count = 1;
    id="#mapLocations";
    if (prefix) {
	id = prefix + " " + id;
    }
    var locations = $(id).attr('class').split(" ");
    count = locations.length;
    $.each(locations, function() {
	$.getJSON('/rest/locations/'+this+'.json', function(data) {
	    sfLocationCollection.locations.push(new sfLocation(data));
	    count--;
	    if (count == 0) {
		sfLocationService.locationCollection = sfLocationCollection;
		sfLocationService.showLocations();
	    }
	});
    });
}

function initMap() {
    loadLocations();
    withLibrary('jUi', function() {
	withLibrary('geoComplete', function() { $("#startAddress").geo_autocomplete(); });
    });
}